//
//  DBExercise.m
//  CareRingApp
//
//  Created by Linktop on 2023/7/17.
//

#import "DBExercise.h"
#import "ConfigModel.h"
#import "DBHistoryDataSr03.h"
#import <MJExtension/MJExtension.h>

NSString * const TABLE_NM_EXER = @"table_exercise";
#if DEBUG
const int MAX_ERERCISE_ONE_DAY = 100; //每天限制

#else
const int MAX_ERERCISE_ONE_DAY = 5; //每天限制5个
#endif
const int EXER_TAKE_DATA_SECONDS = 60; //设备取值的间隔


@implementation DBExercise

+ (NSDictionary *)mj_objectClassInArray
{
    
    return @{@"points": @"ExercisePoint", };
    
}


-(instancetype)initWith:(NSString  * _Nonnull)macAddress
{
    if (self = [super init]) {
        self->_macAddress = macAddress;
        self->_rowId = -1;
    }
    return self;
}



+(void)createTable
{
    
    WEAK_SELF
    [[DbManager instance] dbQueue:^(sqlite3 * _Nonnull db) {
        STRONG_SELF
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (macAddress TEXT NOT NULL ,duration INTEGER, startDate DOUBLE NOT NULL, endDate DOUBLE, formatTimeString TEXT, exerType INTEGER, exerLevel INTEGER,  PRIMARY KEY(macAddress, startDate))", TABLE_NM_EXER];
        
        char * err;
        if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
            //失败
            //            sqlite3_close(db);
            NSAssert(NO, @"建表失败! %s",err);
        }
        DebugNSLog(@"建表成功 %@", TABLE_NM_EXER);
    }];
    
    
}


+(void)queryBy:(NSString * _Nonnull)macIn BeginDate:(NSDate *)beginDate EndDate:(NSDate *)enDate OrderBeTimeDesc:(BOOL)isDesc
      Cpmplete:(void(^)(NSMutableArray<DBExercise *> *results))cmpBlk
{
    
    WEAK_SELF
    [[DbManager instance] dbQueue:^(sqlite3 * _Nonnull db) {
        
        STRONG_SELF
        NSString *sql =  [NSString stringWithFormat:@"SELECT rowid, macAddress  ,duration , startDate, endDate , formatTimeString , exerType , exerLevel   FROM %@ WHERE macAddress = ? AND startDate BETWEEN ? AND ?  ORDER BY startDate %@", TABLE_NM_EXER, isDesc ? @"DESC" : @"ASC"];
        sqlite3_stmt *stmt;
        NSMutableArray<DBExercise *> *results = [NSMutableArray new];
        if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil) == SQLITE_OK) {
            
            sqlite3_bind_text(stmt, 1, [macIn UTF8String], -1, NULL);
            sqlite3_bind_double(stmt, 2, [beginDate timeIntervalSince1970]);
            sqlite3_bind_double(stmt, 3, [enDate timeIntervalSince1970]);
            
            
            
            while (sqlite3_step(stmt) == SQLITE_ROW) {
                DBExercise *exerModel = [[DBExercise alloc]init];
                if (sqlite3_column_type(stmt, 0) != SQLITE_NULL) {
                    exerModel->_rowId = sqlite3_column_int(stmt, 0);
                }
                
                char *mac = (char *)sqlite3_column_text(stmt, 1);
                exerModel->_macAddress = [[NSString alloc] initWithUTF8String:mac];
                
                exerModel.duration = @(sqlite3_column_int(stmt, 2));
                double startDate = sqlite3_column_double(stmt, 3);
                exerModel.startDate = [NSDate dateWithTimeIntervalSince1970:startDate];
                
                double endDate = sqlite3_column_double(stmt, 4);
                exerModel.endDate = [NSDate dateWithTimeIntervalSince1970:endDate];
                
                char * formatTimeString = (char *)sqlite3_column_text(stmt, 5);
                exerModel.formatTimeString = [[NSString alloc] initWithUTF8String:formatTimeString];
                exerModel.exerType = sqlite3_column_int(stmt, 6);
                exerModel.exerLevel = sqlite3_column_int(stmt, 7);
                
                
                [results addObject:exerModel];
            }
            
        }
        
        sqlite3_finalize(stmt);
        if (cmpBlk) {
            dispatch_async(dispatch_get_main_queue(), ^{
                cmpBlk(results);
            });
        }
    }];
    
    
}



-(void)queryPoints:(void(^)(NSMutableArray <ExercisePoint *> * points))cmpBLK
{
    if (self.points.count) {
        if (cmpBLK) {
            cmpBLK(self.points);
        }
        return;
    }
    WEAK_SELF
    // 查表
    [DBHistoryDataSr03 queryForSportBy:self.macAddress Begin:self.startDate End:self.endDate OrderBeTimeDesc:NO Cpmplete:^(NSMutableArray<NSDictionary *> * _Nonnull results) {
        STRONG_SELF
        NSMutableArray<ExercisePoint *> *points = [ExercisePoint mj_objectArrayWithKeyValuesArray:results];
        strongSelf.points = points;
        if (cmpBLK) {
            cmpBLK(strongSelf.points);
        }
    }];
    
    
}




//+(void)dropTable {
//#if DEBUG
//
//    [[HMDBManager instance].dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
//        //创建数据库表
//        NSString   * sql = [NSString stringWithFormat:@"DROP TABLE %@", TABLE_NM_EXER];
//
//        bool succ = [db executeUpdate:sql];
//        NSLog(@"drop table %@ result =%d ", TABLE_NM_EXER, succ);
//
//    }];
//#endif
//}

-(void)insert:(void(^)(BOOL succ))complete
{
    
    WEAK_SELF
    [[DbManager instance] dbQueue:^(sqlite3 * _Nonnull db) {
        STRONG_SELF
        if (!strongSelf.startDate || !strongSelf.duration || !strongSelf.macAddress) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (complete) {
                    complete(NO);
                }
            });
            return;
        }
        
        NSDateFormatter *fmt = [NSDateFormatter new];
        fmt.dateFormat = @"yyyy-MM-dd";
        
        strongSelf.endDate = [strongSelf.startDate dateByAddingTimeInterval:strongSelf.duration.doubleValue * 60];
        
        strongSelf.formatTimeString = [fmt stringFromDate:strongSelf.startDate];
        
        NSString *sqlString = [NSString stringWithFormat:  @"INSERT OR IGNORE INTO %@ (macAddress , duration , startDate , endDate , exerType , exerLevel, formatTimeString) VALUES (?,?,?,?,?,?,?)", TABLE_NM_EXER];
        sqlite3_stmt *stmt;
        if (sqlite3_prepare_v2(db, [sqlString UTF8String], -1, &stmt, nil) == SQLITE_OK) {
            
            
            sqlite3_bind_text(stmt, 1, [strongSelf.macAddress UTF8String], -1, NULL);
            sqlite3_bind_int(stmt, 2, strongSelf.duration.intValue);
            sqlite3_bind_double(stmt, 3, (NSUInteger)[strongSelf.startDate timeIntervalSince1970]);
            sqlite3_bind_double(stmt, 4, [strongSelf.endDate timeIntervalSince1970]);
            sqlite3_bind_int(stmt, 5, (int)strongSelf.exerType);
            sqlite3_bind_int(stmt, 6, (int)strongSelf.exerLevel);
            sqlite3_bind_text(stmt, 7, [strongSelf.formatTimeString UTF8String], -1, NULL);
        }
        
        BOOL succ = sqlite3_step(stmt) == SQLITE_DONE;
        
        sqlite3_finalize(stmt);
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (complete) {
                complete(succ);
            }
        });
        
    }];
    
}


-(void)updateEndDate:(void(^)(BOOL succ))complete
{
    
    WEAK_SELF
    
    [[DbManager instance] dbQueue:^(sqlite3 * _Nonnull db) {
        STRONG_SELF
        
        float minutes = fabs([strongSelf.startDate timeIntervalSinceDate:strongSelf.endDate]) / 60;
        strongSelf.duration = @((int)minutes); // 根据实际结束更新
        
        NSString *sqlString = [NSString stringWithFormat:  @"UPDATE %@ set endDate= ? , duration = ? WHERE rowid = ?", TABLE_NM_EXER];
        
        sqlite3_stmt *stmt;
        if (sqlite3_prepare_v2(db, [sqlString UTF8String], -1, &stmt, nil) == SQLITE_OK) {
            sqlite3_bind_double(stmt, 1, [strongSelf.endDate timeIntervalSince1970]);
            
            sqlite3_bind_int(stmt, 2, strongSelf.duration.intValue);
            sqlite3_bind_int(stmt, 3, strongSelf.rowId);
            
            //            sqlite3_bind_text(stmt, 3, [strongSelf.macAddress UTF8String], -1, NULL);
            //            sqlite3_bind_double(stmt, 4, [strongSelf.startDate timeIntervalSince1970]);
        }
        
        int res =  sqlite3_step(stmt) ;
        BOOL succ = res == SQLITE_DONE;
        sqlite3_finalize(stmt);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (complete) {
                complete(succ);
            }
        });
        
        
    }];
    
    
}





+(void)queryBy:(NSString * _Nonnull)macAddressIn Year:(int)year OrderBeTimeDesc:(BOOL)isDesc Cpmplete:(void(^)(NSMutableArray<DBExercise *> *results))cmpBlk
{
    
    WEAK_SELF
    [[DbManager instance] dbQueue:^(sqlite3 * _Nonnull db) {
        STRONG_SELF
        NSString *sql =  [NSString stringWithFormat:@"SELECT rowid, macAddress, duration , startDate, endDate , formatTimeString , exerType , exerLevel   FROM %@ WHERE macAddress = ? AND formatTimeString LIKE '%d%%' ORDER BY startDate  %@", TABLE_NM_EXER, year, isDesc ? @"DESC" : @"ASC"];
        sqlite3_stmt *stmt;
        NSMutableArray<DBExercise *> *results = [NSMutableArray new];
        if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil) == SQLITE_OK) {
            
            
            sqlite3_bind_text(stmt, 1, [macAddressIn UTF8String], -1, NULL);
            //            sqlite3_bind_int(stmt, 2, year);
            
            
            while (sqlite3_step(stmt) == SQLITE_ROW) {
                DBExercise *exerModel = [[DBExercise alloc]init];
                
                if (sqlite3_column_type(stmt, 0) != SQLITE_NULL) {
                    exerModel->_rowId = sqlite3_column_int(stmt, 0);
                }
                
                char *mac = (char *)sqlite3_column_text(stmt, 1);
                exerModel->_macAddress = [[NSString alloc] initWithUTF8String:mac];
                
                exerModel.duration = @(sqlite3_column_int(stmt, 2));
                double startDate = sqlite3_column_double(stmt, 3);
                exerModel.startDate = [NSDate dateWithTimeIntervalSince1970:startDate];
                
                double endDate = sqlite3_column_double(stmt, 4);
                exerModel.endDate = [NSDate dateWithTimeIntervalSince1970:endDate];
                
                char * formatTimeString = (char *)sqlite3_column_text(stmt,5);
                exerModel.formatTimeString = [[NSString alloc] initWithUTF8String:formatTimeString];
                exerModel.exerType = sqlite3_column_int(stmt, 6);
                exerModel.exerLevel = sqlite3_column_int(stmt, 7);
                
                
                
                
                
                [results addObject:exerModel];
            }
            
        }
        
        sqlite3_finalize(stmt);
        if (cmpBlk) {
            dispatch_async(dispatch_get_main_queue(), ^{
                cmpBlk(results);
            });
        }
    }];
    
}


-(NSString *)stringForLevel
{
    return [[self class] stringForLevel:self.exerLevel];
}

+(NSString *)stringForLevel:(EXER_LEVEL)lv {
    switch (lv) {
        case LEVEL_EASY:
        {
            return @"Easy";
        }
            break;
        case LEVEL_MODERATE:
        {
            return @"Normal";
        }
            break;
        case LEVEL_HARD:
        {
            return @"Hard";
        }
            break;
        default:
            
            break;
    }
    
    return nil;
}

-(BOOL)isEnd {
    
    return [self.endDate timeIntervalSince1970] <= [[NSDate date] timeIntervalSince1970];
}

-(NSString *)durationString:(BOOL)isRealtime {
    if (isRealtime) {
        NSTimeInterval diff = [[NSDate date] timeIntervalSinceDate:self.startDate];
        diff /= 60.0f; // 转换为分钟
        int dura = self.duration.intValue;
        if (diff < self.duration.doubleValue) {
            dura = (int)(diff);
        }
        
        return [[self class] durationString:dura];
        
    }
    
    return [[self class] durationString:self.duration.intValue];
    
    
}

+(NSString *)durationString:(int)duration
{
    NSString *str = @"";
    if (duration < 60) {
        str = [NSString stringWithFormat:@"%d%@", duration, _L(L_UNIT_MINNUTE)];
    }
    
    if (duration >= 60) {
        
        int hour = duration / 60;
        int min = duration % 60;
        
        str = [NSString stringWithFormat:@"%d%@", hour, _L(L_UNIT_HOUR)];
        if (min != 0) {
            str = [str stringByAppendingFormat:@" %d%@", min, _L(L_UNIT_MINNUTE)];
        }
    }
    
    return str;
}

-(NSString *)stringForExerType
{
    
    return [[self class] stringForExerType:self.exerType];
}

+(NSString *)stringForExerType:(EXER_TYPE)type
{
    switch (type) {
        case EXER_UNKNOW:
        {
            return @"";
        }
            break;
        case EXER_RUN:
        {
            return @"Running in door";
        }
            break;
        case EXER_WALK:
        {
            return @"Walking";
        }
            break;
        case  EXER_RUN_OUTDOOR :
        {
            return @"Running out door";
            
        }
            break;
        case EXER_RIDE_INDOOR:
        {
            return @"Bike in the house";
            
        }
            break;
        case EXER_RIDE_OUTDOOR :
        {
            return @"Bike out door";
            
        }
            break;
        case EXER_MOUTAIN_BIKE :
        {
            return @"Moutain bike";
            
        }
            break;
        case EXER_SWIM :
        {
            return @"Swiming";
            
        }
            break;
        case EXER_Hatha_Yoga://  哈他瑜伽
        {
            return @"Hatha Yoga";
        }
            break;
        case EXER_Iyengar_Yoga: // 艾扬格瑜伽
        {
            return @"Iyengar Yoga";
        }
            break;
        case EXER_Vinyasa_Yoga:// 流瑜伽
        {
            return @"Vinyasa Yoga";
        }
            break;
        case EXER_Power_Yoga://  力量瑜伽
        {
            return @"Power Yoga";
        }
            break;
        case EXER_Hot_Yoga:// 热瑜伽
        {
            return @"Hot Yoga";
        }
            break;
        case EXER_Ashtanga_Yoga:// 阿斯汤伽瑜伽
        {
            return @"Ashtanga Yoga";
        }
            break;
        default:
            
            break;
    }
    
    return @"";
    
}



///
/// - Parameters:
///   - height: User's height (Unit: m)
///   - bodyWeight: User's weight (Unit: kg)
///   - sumStepIncrease: Increased number of steps during workout.
-(float)calcBurnCaloByBodyHeight:(float)height BodyWeight:(float)bodyWeight InsreaseStep:(NSInteger)sumStepIncrease
{
    
    NSInteger step = sumStepIncrease;
    
    float calo = 0;
    
    if (self.exerType ==  EXER_WALK ||
        self.exerType ==EXER_RUN ||
        self.exerType ==EXER_RUN_OUTDOOR)
    {
        // 计算卡路里
        // 体重系数
        float massIndex = 0;
        switch (self.exerLevel) {
            case LEVEL_EASY:  // 简单
            {
                massIndex = 0.05f;
            }
                break;
            case LEVEL_MODERATE:// 中等
            {
                massIndex = 0.08f;
            }
                break;
            case LEVEL_HARD:  // 困难
            {
                massIndex = 0.1f;
            }
                break;
            default:
                break;
        }
        
        float stepLength = height * 0.45 / 100; // step size
        calo = stepLength * massIndex * step;
        
    }
    
    
    if (self.exerType ==  EXER_RIDE_INDOOR ||
        self.exerType == EXER_RIDE_OUTDOOR ||
        self.exerType == EXER_MOUTAIN_BIKE ||
        self.exerType == EXER_SWIM)
    {
        NSTimeInterval timeHour = [self.endDate timeIntervalSinceDate:self.startDate] / 3600.0f;
        calo = self.met * timeHour * bodyWeight;
        
    }
    
    if (self.exerType ==  EXER_Hatha_Yoga ||
        self.exerType ==  EXER_Iyengar_Yoga ||
        self.exerType ==  EXER_Vinyasa_Yoga ||
        self.exerType ==  EXER_Power_Yoga ||
        self.exerType ==  EXER_Hot_Yoga ||
        self.exerType ==  EXER_Ashtanga_Yoga)
    {
        NSTimeInterval timeHour = [self.endDate timeIntervalSinceDate:self.startDate] / 3600.0f;
        calo = self.met * timeHour * bodyWeight;
    }
    
    
    return calo;
    
    
}

-(float)met {
    float met = 1;
    
    if (self.exerType == EXER_RIDE_INDOOR
        || self.exerType == EXER_RIDE_OUTDOOR )
    {
        switch (self.exerLevel) {
            case LEVEL_EASY:
            {
                met = 4.34f;
            }
                break;
            case LEVEL_MODERATE:
            {
                met = 6.02f;
            }
                break;
            case LEVEL_HARD:
            {
                met = 8.54f;
            }
                break;
            default:
                break;
        }
    }
    
    
    if (self.exerType == EXER_MOUTAIN_BIKE)
    {
        switch (self.exerLevel) {
            case LEVEL_EASY:
            {
                met = 6.02f;
            }
                break;
            case LEVEL_MODERATE:
            {
                met = 7.02f;
            }
                break;
            case LEVEL_HARD:
            {
                met = 12.57f;
            }
                break;
            default:
                break;
        }
    }
    
    if (self.exerType == EXER_SWIM)
    {
        switch (self.exerLevel) {
            case LEVEL_EASY:
            {
                met = 3.82f;
            }
                break;
            case LEVEL_MODERATE:
            {
                met = 6.85f;
            }
                break;
            case LEVEL_HARD:
            {
                met = 8.54f;
            }
                break;
            default:
                break;
        }
    }
    
    if (self.exerType == EXER_Hatha_Yoga) {
        met = 2.5f;
    }//  哈他瑜伽
    if (self.exerType == EXER_Iyengar_Yoga) {
        met =  2.3f;
    } // 艾扬格瑜伽
    if (self.exerType == EXER_Vinyasa_Yoga) {
        met = 5.0f;
    }// 流瑜伽
    if (self.exerType == EXER_Power_Yoga) {
        met =  4.0f;
    }//  力量瑜伽
    if (self.exerType == EXER_Hot_Yoga) {
        met = 6.0f;
    }// 热瑜伽
    if (self.exerType == EXER_Ashtanga_Yoga) {
        met =  4.8f;
    }// 阿斯汤伽瑜伽
    
    
    return met;
}

@end


@implementation  ExercisePoint


@end

